import ij.IJ;
import ij.ImagePlus;
import ij.ImageStack;
import ij.WindowManager;
import ij.plugin.PlugIn;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import ij.IJ;
import ij.ImagePlus;
import ij.measure.ResultsTable;
import ij.plugin.PlugIn;
import ij.process.ImageConverter;
import ij.process.ImageProcessor;
import ij.*;
import ij.process.*;
import ij.gui.*;
import ij.plugin.filter.Analyzer;


import ij.plugin.Duplicator;

public class Analysis_  implements PlugIn {

	public static String title = "Analyse Cell Fibers";
	public int[] wList;
	ImagePlus Channel1, Channel2, imp_rgb_original;

	static ImagePlus mask_Channel1, mask_Channel2, mask;
	public static int NUM_GRID_CELL = 60;
	static final int CENTROID = 0;

	public String[] titles;
	public static int numVertex_User_Defined = 40;
	public ImagePlus[] image = new ImagePlus[2];
	static ImagePlus imp_rgb_modified;
	static ImageProcessor ip_rgb_modified;

	public static String[] channel = {"Red", "Green", "Blue"};
	String image_location_red = "";//"E:\\RA\\NIST-subcellular_feature_dataset_1\\2009_04_20_24h_TxRed.tiff\\2010_04_20_A10_24hRed_00008.tif";
	String image_location_green = "";//"E:\\RA\\NIST-subcellular_feature_dataset_1\\2009_04_20_24h_A488.tiff\\2010_04_20_A10_24hGreen_00008.tif";
	static GenericDialog gd = null;
	
	static double minX=1000000000,minY=1000000000,maxX=0,maxY=0;
	static int bucket_size = 3;
	static int fall_c = 2;

	public boolean showUserBandDialog(){

		GenericDialog dialog = new GenericDialog(title);

		dialog.addMessage("Click Ok if you want to manually Input new vertices else press cancel");
		dialog.showDialog();

		if (dialog.wasCanceled())
			return false;

		return true;

	}


	public boolean showDialog(){

		GenericDialog dialog = new GenericDialog(title);
		for (int i = 0; i < image.length; i++) {
			dialog.addChoice(channel[i] + " channel:", titles, titles[i]);
		}
      
        dialog.addNumericField("Number of vertices: ", (int) Analysis_.NUM_GRID_CELL, 0);
        dialog.addNumericField("Normalization factor: ", (int) Analysis_.bucket_size, 0);
        dialog.addNumericField("Fall of Constant: ", (int) Analysis_.fall_c, 0);
		dialog.showDialog();

		if (dialog.wasCanceled())
			return false;

		for (int i = 0; i < image.length; i++) {
			image[i] = WindowManager.getImage(wList[dialog.getNextChoiceIndex()]);
		}
   
		Analysis_.NUM_GRID_CELL = (int)dialog.getNextNumber();
		
		Analysis_.bucket_size = (int)dialog.getNextNumber();
		
		Analysis_.fall_c = (int)dialog.getNextNumber();
		//image[0].show();
		//image[1].show();

		return true;

	}




	public void run(String arg) {




		wList = WindowManager.getIDList();
		if (wList==null || wList.length<2) {
			IJ.showMessage(title, "There must be two images open");
			return;
		}

		titles = new String[wList.length];
		for (int i=0; i<wList.length; i++) {
			ImagePlus imp = WindowManager.getImage(wList[i]);
			if (imp != null)
				titles[i] = imp.getTitle();
			else
				titles[i] = "";
		}

		if (!showDialog()) return;

		// check image properties
		
		if( (image[0].getWidth()!= image[1].getWidth())  || (image[0].getHeight()!= image[1].getHeight()) )
		{
			IJ.showMessage(title, "Images should have same height and width");
			return;
		}

		if(Analysis_.bucket_size <= 0 || Analysis_.bucket_size > 7)
		 {IJ.showMessage("Enter valid normalization factor between 1-6");
		  return;
		 }


		if(Analysis_.fall_c < 0 || Analysis_.fall_c > 5)
		 {IJ.showMessage("Enter valid fall of constant");
		  return;
		 }
		
		// ************************* Mask Generation ******************************

		maskChannel mC = new maskChannel();
		//mask_Channel1 = IJ.openImage(image_location_red); 
		mask_Channel1 = new Duplicator().run(image[0]);

		mC.mask_channel(mask_Channel1);

		//mask_Channel2 = IJ.openImage(image_location_green);
		mask_Channel2 = new Duplicator().run(image[1]);

		mC.mask_channel(mask_Channel2);

		//      mask = mC.merge_masks(mask_Channel1, mask_Channel2);
		//      mask.show();




		for(int i =0;i<mask_Channel1.getWidth();i++)
			for(int j =0;j<mask_Channel1.getHeight();j++)
			{
				if((mask_Channel1.getProcessor().getPixel(i, j) == 255) && (mask_Channel2.getProcessor().getPixel(i, j) == 255)){

					mask_Channel1.getProcessor().putPixel(i, j, 255);
					mask_Channel2.getProcessor().putPixel(i, j, 255);
				}
				else
				{
					mask_Channel1.getProcessor().putPixel(i, j, 0);
					mask_Channel2.getProcessor().putPixel(i, j, 0);
				}
			}
		
		for(int i =0;i<mask_Channel1.getWidth();i++)
			for(int j =0;j<mask_Channel1.getHeight();j++)
			{
				if((mask_Channel1.getProcessor().getPixel(i, j) == 255) && (mask_Channel2.getProcessor().getPixel(i, j) == 255)){

					if (i < minX)
					minX = i;
					if (i > maxX)
					maxX = i;
					
					if(j < minY)
					minY =j;
					if(j > maxY)
						maxY =j;
				}
		}
			
		
		//System.out.print("minX: "+minX +"maxX: "+maxX +" minY: "+minY +" maxY: "+maxY);
		
		//mask_Channel1.show();
		//mask_Channel2.show();

		// *************************** Normalize *******************************
		normalize_channel nc = new normalize_channel(); 

		//Channel1 = IJ.openImage(image_location_red);
		Channel1 = new Duplicator().run(image[0]);

		//Channel2 = IJ.openImage(image_location_green);
		Channel2 = new Duplicator().run(image[1]);

		nc.normalize(Channel1, mask_Channel1,mask_Channel2, "red");
		nc.normalize(Channel2, mask_Channel2,mask_Channel2, "green");

		//Channel1.show();
		//Channel2.show();

		// ************************** Merge Channel ***************************

		merge_Channel merge = new merge_Channel();

		ImageStack rgb = merge.mergeStacks(Channel1.getWidth(), Channel1.getHeight(), Channel1.getStackSize(), Channel1.getStack(), Channel2.getStack(), null, true);

		imp_rgb_original = new ImagePlus("RGB", rgb);

		imp_rgb_original.show();

		imp_rgb_modified = NewImage.createRGBImage("Inverted image", imp_rgb_original.getWidth(), imp_rgb_original.getHeight(),1, NewImage.FILL_BLACK);

		ip_rgb_modified = imp_rgb_modified.getProcessor();
		ip_rgb_modified.copyBits(imp_rgb_original.getProcessor(),0,0,Blitter.COPY);

		imp_rgb_modified.show();
		imp_rgb_original.show();

		
		// ************************* Generate and Score Band **************************

		center_mass cm = new center_mass();

		cm.find_center_of_mass(mask_Channel1,mask_Channel2);


		System.out.print("xmass "+center_mass.xMass+" yMass: "+center_mass.yMass);
		band bd = new band();
		bd.find_vertex(imp_rgb_original, mask_Channel1,mask_Channel2);


		scores sc = new scores();
		sc.band_score(imp_rgb_original, mask_Channel1,mask_Channel2);

		draw dr = new draw();
		dr.draw_edges_with_std(imp_rgb_original);

		if (!showUserBandDialog()) return;


		Mouse_Listener ml = new Mouse_Listener();
		ml.listen(imp_rgb_modified);



	}
}